package org.simplesocket.simplenettycore.config;

import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.simplesocket.simplenettycore.utils.SimpleNettyUtils;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Data
public class SimpleNettyConfig {
    
    private String basePackageName = SimpleNettyUtils.ClassUtil.getUserBasePackageName();
    
    private String host = "127.0.0.1";
    
    private int port = 8080;
    
    private int bossThreadNumber = 1;
    
    private int workerThreadNumber = 4;
    
    private EventLoopGroup boss;
    
    private EventLoopGroup worker;
    
    private List<ConfigLoader> configLoaderList = new ArrayList<>();
    
    private SimpleNettyConfig() {
        log.info("Preparing to load event loop groups ...");
        this.boss = new NioEventLoopGroup(bossThreadNumber);
        if (!legalWorkerThreadNum(workerThreadNumber)) {
            throw new RuntimeException("illegal worker thread number");
        }
        this.worker = new NioEventLoopGroup(workerThreadNumber);
        log.info("Load event loop groups done ...");
    }
    
    private static boolean legalWorkerThreadNum(int workerThreadNum) {
        if (workerThreadNum == 0) {
            log.error("Fail to run server.");
            System.out.println("""
                    
                    \tThis machine cannot run this service \
                    because the number of threads on this machine
                    \tis less than 4\
                    and cannot meet the minimum \
                    configuration for running the service ...""");
            return false;
        }
        
        return true;
    }
    
    public static Builder builder() {
        return new Builder();
    }
    
    public static class Builder{
        private final SimpleNettyConfig config;
        
        private Builder() {
            this.config = new SimpleNettyConfig();
        }
        
        public Builder basePackageName(String packageName){
            this.config.setBasePackageName(packageName);
            return this;
        }
        
        public Builder workerThreadNumber(int number){
            this.config.setWorkerThreadNumber(number);
            return this;
        }
        
        public Builder bossThreadNumber(int number){
            this.config.setBossThreadNumber(number);
            return this;
        }
        
        public Builder host(String host){
            config.setHost(host);
            return this;
        }
        
        public Builder port(int port){
            config.setPort(port);
            return this;
        }
        
        public Builder configLoader(ConfigLoader configLoader){
            this.config.configLoaderList.add(configLoader);
            return this;
        }
        
        public SimpleNettyConfig build(){
            return config;
        }
    }
}
